<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\AppOffline;
use App\Models\UserInfo;
use \Cache;

class SwooleServer extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'swoole:server';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'swoole websocket';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //创建server
        $server = new \Swoole\WebSocket\Server("0.0.0.0", 9502,SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);

        //配置参数
        $server ->set([
            'daemonize' => true, //守护进程化。
            //配置SSL证书和密钥路径
            'ssl_cert_file' => "/www/server/panel/vhost/cert/ws.yuchengrfid.com/fullchain.pem",
            'ssl_key_file'  => "/www/server/panel/vhost/cert/ws.yuchengrfid.com/privkey.pem"
        ]);

        //连接成功回调
        $server->on('open', function (\Swoole\WebSocket\Server $server, $request) {
            $this->info($request->fd . '链接成功');
        });

        //收到消息回调
        $server->on('message', function (\Swoole\WebSocket\Server $server, $frame) {
            $data = json_decode($frame->data,true);
            if($data['flag'] == 'init'){
//                //用户刚连接的时候初始化，每个用户登录时记录该用户对应的fd
                Cache::put($data['from'], $frame->fd);
                //处理发给该用户的离线消息
                $re = AppOffline::where(['to'=>$data['from'] , 'from'=>$data['to'] , 'status'=>0 ])
                    ->orderby('addtime')
                    ->get();
                if(!empty($re)){
                    foreach($re as $content){
                        $content = json_encode($content);
                        $server->push($frame->fd , $content);
                    }
                }
                //设置消息池中的消息为已发送
                AppOffline::where(['to'=>$data['from'] , 'from'=>$data['to'] ])
                    ->update(['status'=>1]);
            }else if($data['flag'] == 'msg'){
                //非初始化的信息发送，一对一聊天，根据每个用户对应的fd发给特定用户
                $tofd = Cache::get($data['to']);
                $fds = []; //所有在线的用户(打开聊天窗口的用户)
                foreach($server->connections as $fd){
                    array_push($fds, $fd);
                }
                if(in_array($tofd,$fds)){
                    //记录聊天
                    AppOffline::create([
                        'to'=>$data['to'] ,
                        'from'=>$data['from'] ,
                        'content'=>$data['content'] ,
                        'type'=>$data['type'] ,
                        'status'=>1,
                        'addtime'=>time() ,
                    ]);

                    $tmp['from'] = $data['from']; //消息来自于谁
                    $tmp['content']  = $data['content']; //消息内容
                    $tmp['type']  = $data['type']; //消息内容
                    $re = json_encode($tmp);
                    $server->push($tofd , $re);
                }else{
                    //该玩家不在线(不在聊天室内)，将信息发送到离线消息池
                    AppOffline::create([
                        'to'=>$data['to'] ,
                        'from'=>$data['from'] ,
                        'content'=>$data['content'] ,
                        'type'=>$data['type'] ,
                        'status'=>0 ,
                        'addtime'=>time() ,
                    ]);
                }
            }else if($data['flag'] == 'group'){
                //todo 群聊

            }else if($data['flag'] == 'all'){
                //全站广播
                foreach($server->connections as $fd){
                    $server->push($fd , $data);
                }
            }
        });

        //关闭链接回调
        $server->on('close', function ($ser, $fd) {
            $this->info($fd . '断开链接');
        });

        $server->start();
    }
}